package com.tsystems.java.school.hometask;

import java.util.*;
import java.io.*;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

/**
 @author Sivkov Evgenii
 Instance of class imitates data table. There are some string keys in the first column and integer values in the second column.
@param logger is tool to log run time information about running application
 */

public class DataStorage {
	
	/**
	 Constructs a new empty TreeMap<String, Integer>, sorted according to the keys natural order.
	 */
	public DataStorage(){
		
		data = new TreeMap<String, Integer>();
		
		logger = Logger.getLogger(DataStorage.class);
		PropertyConfigurator.configure("conf/PropertyFile1.properties");
		
	}
	
	/**
	 This method reads data from the file and saves them to the Map<String, Integer> data. Unique strings are the keys and amount of the string in the file are values in this map.
	 @param fileName is the name of target file to be scanned.
	 * @throws FileNotFoundException 
	 @throws FileNotFoundException if source is not found
	 */
	public void readData(String fileName) throws FileNotFoundException{

		//create new stream to read data
		File file = new File(fileName);
		Scanner in = new Scanner(file);
		logger.info("create new stream named " + fileName);
		
		while (in.hasNextLine()){
			
			//get the next string with leading and trailing whitespace omitted
			String next = in.nextLine().trim(); 
			
			//skip empty string
			if (!next.equals("")){
				
				if (logger.isDebugEnabled()){
					
					logger.debug("next symbol isn't whitespace. next = " + next);
				}
				
				if(data.containsKey(next)){
					
					if (logger.isDebugEnabled()){
						
						logger.debug("data contains key" + next);
					}
					//increase value associated with the key "next"
					int amount = data.get(next);
					data.put(next, amount + 1);
				}
				else  {
					
					//put new data with key = 1 to the Map<String, Integer> data
					data.put(next, 1);
				}
			}	
		}
		in.close();
		logger.info("stream " + fileName +  "closed");
	}

	/**
	 This method writes data in the output files. There are only unique strings (sorted) in the first file and repeated strings in the second file.
	 @param pathName points to the directory in which two output files'll create.
	 @throws FileNotFoundException if source is not found
	 */
	public void writeData(String pathName) throws FileNotFoundException {
		
		//create output files using pathname
		File fileUniqueStrings = new File(pathName, "outputUnique.txt");
		File fileNotUniqueStrings = new File(pathName, "outputNotUnique.txt");
		
		//create instances of PrintWriter to write output data
		PrintWriter outUnique = new PrintWriter(fileUniqueStrings);
		PrintWriter outNotUnique = new PrintWriter(fileNotUniqueStrings);
		logger.info("create input and output streams in the directory " + pathName);
		
		for (Map.Entry<String, Integer> entry : data.entrySet()){
			
			String key = entry.getKey();
			int value = entry.getValue();
			if (value > 1){
				
				outNotUnique.println(key + " - " + value);
				if (logger.isDebugEnabled()) {
				
					logger.debug("write record to the file, containing not unique records");
				}
				
			}
			
			outUnique.println(key);
			if (logger.isDebugEnabled()) {
			
				logger.debug("write record to the file, containig unique reords");
			}
			
		}
		outUnique.close();
		outNotUnique.close();
		logger.info("output streams closed");
	}
	
	private Map<String, Integer> data;
	private Logger logger;
}
